package org.ourgrid.worker.business.requester;

import java.util.ArrayList;
import java.util.List;

import org.ourgrid.common.interfaces.to.WorkerStatus;
import org.ourgrid.common.internal.IResponseTO;
import org.ourgrid.common.internal.RequesterIF;
import org.ourgrid.common.internal.response.LoggerResponseTO;
import org.ourgrid.common.internal.response.ReleaseResponseTO;
import org.ourgrid.worker.business.controller.ExecutionController;
import org.ourgrid.worker.business.controller.WorkerController;
import org.ourgrid.worker.business.dao.WorkerDAOFactory;
import org.ourgrid.worker.business.dao.WorkerStatusDAO;
import org.ourgrid.worker.business.messages.WorkerManagementClientFailureControllerMessages;
import org.ourgrid.worker.request.WMCDoNotifyFailureRequestTO;
import org.ourgrid.worker.response.CancelReportAccountingActionResponseTO;

public class WMCDoNotifyFailureRequester implements RequesterIF<WMCDoNotifyFailureRequestTO> {

	public List<IResponseTO> execute(WMCDoNotifyFailureRequestTO request) {
		// Currently, any failure detected by the worker will make it
		// disconnect. If it's connected to a broker, it will disconnect from
		// it, drop whatever task it was running, and be available for
		// connection, by which point the peer will a attempt to connect to it.

		List<IResponseTO> responses = new ArrayList<IResponseTO>();

		if (!request.getMasterPeerPublicKey().equals(request.getMonitorablePublicKey())) {
			responses.add(new LoggerResponseTO(WorkerManagementClientFailureControllerMessages
					.getUnknownPeerFailsMessage(request.getMonitorableID()), LoggerResponseTO.WARN));

			return responses;
		}

		WorkerStatusDAO workerStatusDAO = WorkerDAOFactory.getInstance().getWorkerStatusDAO();

		if (workerStatusDAO.getMasterPeerDeploymentID() == null) {
			responses.add(new LoggerResponseTO(WorkerManagementClientFailureControllerMessages
					.getUndefinedMasterPeerFailsMessage(request.getMonitorableID()), LoggerResponseTO.WARN));

			return responses;
		}

		boolean isWorkingState = workerStatusDAO.isWorkingState();

		if (workerStatusDAO.isAllocated()) {
			WorkerController.getInstance().interruptWorking(responses, true);
		}

		if (isWorkingState) {
			ExecutionController.getInstance().beginAllocation(responses);
		}

		responses.add(new LoggerResponseTO(WorkerManagementClientFailureControllerMessages
				.getMasterPeerFailsMessage(request.getMonitorableID()), LoggerResponseTO.WARN));

		workerStatusDAO.masterPeerFails();
		workerStatusDAO.setStatus(WorkerStatus.IDLE);

		CancelReportAccountingActionResponseTO cancelReportAccountingTO = new CancelReportAccountingActionResponseTO();
		responses.add(cancelReportAccountingTO);

		WorkerDAOFactory.getInstance().getWorkAccountingDAO().resetAccountings();

		ReleaseResponseTO releaseTO = new ReleaseResponseTO();
		releaseTO.setStubAddress(request.getMonitorableAddress());

		responses.add(releaseTO);

		return responses;
	}
}
